package com.loren.demo29.utils;

import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import org.springframework.web.multipart.MultipartFile;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class MinioUtils {

    private final MinioClient minioClient;

    public MinioUtils(String endpoint, String accessKey, String secretKey) {
        // 0意味着没有超时
        this(endpoint, accessKey, secretKey, 0, 0, 0);
    }

    public MinioUtils(String endpoint, String accessKey, String secretKey, long connectTimeout, long writeTimeout, long readTimeout) {
        this.minioClient = MinioClient
                .builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .build();
        minioClient.setTimeout(connectTimeout, writeTimeout, readTimeout);
    }

    /**
     * 判断bucket是否存在
     *
     * @param bucket bucket名称
     */
    public boolean existBucket(String bucket) {
        try {
            return this.minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 创建bucket
     *
     * @param bucket bucket名称
     */
    public void makeBucket(String bucket) {
        try {
            if (!this.existBucket(bucket)) {
                this.minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取bucket列表
     */
    public List<Bucket> listBuckets() {
        try {
            return this.minioClient.listBuckets();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }

    /**
     * 删除bucket
     *
     * @param bucket bucket名称
     */
    public void removeBucket(String bucket) {
        try {
            if (this.existBucket(bucket)) {
                this.minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucket).build());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 上传文件
     *
     * @param bucket bucket名称
     * @param object 对象名
     * @param file   文件对象
     */
    public void upload(String bucket, String object, MultipartFile file) {
        try {
            minioClient.putObject(
                    PutObjectArgs
                            .builder()
                            .bucket(bucket)
                            .object(object)
                            .contentType(file.getContentType())
                            .stream(file.getInputStream(), file.getSize(), -1)
                            .build()
            );
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 上传文件
     *
     * @param bucket      bucket名称
     * @param object      对象名
     * @param inputStream 文件流
     */
    public void upload(String bucket, String object, InputStream inputStream) {
        try {
            minioClient.putObject(
                    PutObjectArgs
                            .builder()
                            .bucket(bucket)
                            .object(object)
                            .stream(inputStream, inputStream.available(), -1)
                            .build()
            );
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取文件流
     *
     * @param bucket bucket名称
     * @param object 对象名
     */
    public InputStream getObject(String bucket, String object) {
        try {
            return this.minioClient.getObject(GetObjectArgs.builder().bucket(bucket).object(object).build());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取文件信息
     *
     * @param bucket bucket名称
     * @param object 对象名
     */
    public ObjectStat statObject(String bucket, String object) {
        try {
            return this.minioClient.statObject(StatObjectArgs.builder().bucket(bucket).object(object).build());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 删除文件信息（会同时删除磁盘的文件）
     *
     * @param bucket bucket名称
     * @param object 对象名
     */
    public void removeObject(String bucket, String object) {
        try {
            this.minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(object).build());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取下载链接
     *
     * @param bucket bucket名称
     * @param object 对象名
     * @param expiry 链接过期时间 单位：秒 不得小于1秒及大于7天
     */
    public String getPreSignedObjectUrl(String bucket, String object, int expiry) {
        try {
            return this.minioClient.getPresignedObjectUrl(
                    GetPresignedObjectUrlArgs
                            .builder()
                            .bucket(bucket)
                            .object(object)
                            .expiry(expiry)
                            .method(Method.GET)
                            .build()
            );
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) throws Exception {
        MinioUtils minioUtils = new MinioUtils("http://172.28.128.100:9000", "minio-demo-key", "minio-demo-secret");

        String bucket = "bucket-demo-01";

        String folder = "20221019";
        String filename = "wallhaven-z859ov.png";
        String object = folder + "/" + filename;

//        minioUtils.makeBucket(bucket);
//        System.out.println("make bucket success");

//        FileInputStream fileInputStream = new FileInputStream("D:\\document\\wallhaven\\" + filename);
//        minioUtils.upload(bucket, object, fileInputStream);
//        System.out.println("file upload success");

        String downloadUrl = minioUtils.getPreSignedObjectUrl(bucket, object, (int) TimeUnit.MINUTES.toSeconds(2));
        System.out.println(downloadUrl);

//        ObjectStat objectStat = minioUtils.statObject(bucket, object);
//        System.out.println(objectStat);

//        minioUtils.removeObject(bucket, object);

//        InputStream inputStream = minioUtils.getObject(bucket, object);
//        System.out.println(inputStream);

//        minioUtils.removeBucket(bucket);
    }
}
